package com.dcits.agent.utils;

import com.google.common.base.Splitter;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * @className: TestMain
 * @description:
 * @author: caoyangjie
 * @date: 2025/6/12
 **/
public class GenerateSpringFactories {
    public static void main(String[] args) throws IOException {
        File inputDir = new File("/hxcloud/poc/micro-service-demo/AgentEnhancer/target/dependency");
        File outputDir = new File("/hxcloud/poc/micro-service-demo/AgentEnhancer/target/spring");
        File springOutputDir = new File("/hxcloud/poc/micro-service-demo/AgentEnhancer/target/aot");
        boolean extractFromJar = true;

        if (!outputDir.exists()) {
            outputDir.mkdirs();
        }
        if (!springOutputDir.exists()) {
            springOutputDir.mkdirs();
        }

        File[] files = inputDir.listFiles((dir, name) -> name.endsWith(".jar"));
        if (files != null && extractFromJar) {
            for (File file : files) {
                try (JarFile jarFile = new JarFile(file)) {
                    JarEntry entry = jarFile.getJarEntry("META-INF/spring.factories");
                    if (entry != null) {
                        InputStream inputStream = jarFile.getInputStream(entry);
                        Files.copy(inputStream, Paths.get(outputDir.getPath(), file.getName() + "-spring.factories"), StandardCopyOption.REPLACE_EXISTING);
                    }
                    // 读取META-INF/spring 目录下的所有文件
                    Enumeration<JarEntry> entries = jarFile.entries();
                    while (entries.hasMoreElements()) {
                        entry = entries.nextElement();
                        if (entry.getName().endsWith("META-INF/spring/aot.factories")) {
                            // 将 META-INF/spring 下的所有文件 拷贝 到 /home/caoyangjie/platform/msb/bosc-msp-parent/bosc-msp-payment-service/target/spring
                            Files.copy(jarFile.getInputStream(entry), Paths.get(springOutputDir.getPath(), file.getName()+"-aot.factories"), StandardCopyOption.REPLACE_EXISTING);
                        }
                        if (entry.getName().startsWith("META-INF/spring/")&&!entry.getName().endsWith("META-INF/spring/")) {
                            // 将 META-INF/spring 下的所有文件 拷贝 到 /home/caoyangjie/platform/msb/bosc-msp-parent/bosc-msp-payment-service/target/spring
                            Files.copy(jarFile.getInputStream(entry), Paths.get(springOutputDir.getPath(), file.getName()+"-"+entry.getName().substring(entry.getName().lastIndexOf('/')+1)), StandardCopyOption.REPLACE_EXISTING);
                        }
                    }
                }
            }
        }

        // 遍历 /home/caoyangjie/platform/msb/bosc-msp-parent/bosc-msp-payment-service/target/spring 目录下的所有文件并解析。
        // 将同key的内容合并放到一起
        Map<String, List<String>> mergedFactories = new HashMap<>();

        // 读取目录中的所有 spring.factories 文件
        files = outputDir.listFiles((dir, name) -> name.endsWith("-spring.factories"));
        if (files != null) {
            for (File file : files) {
                System.out.println("Processing: " + file.getName());
                Properties properties = new Properties();
                try (InputStream inputStream = new FileInputStream(file)) {
                    properties.load(inputStream);
                }

                // 合并内容
                for (String key : properties.stringPropertyNames()) {
                    String value = properties.getProperty(key);
                    mergedFactories.computeIfAbsent(key, k -> new ArrayList<>()).addAll(Arrays.asList(value.split(",")));
                }
            }
        }
        Map<String, List<String>> mergedAotFactories = new HashMap<>();
        Map<String, List<String>> mergedTxtFactories = new HashMap<>();
        files = springOutputDir.listFiles((dir, name) -> name.contains(".jar-"));
        if (files != null) {
            for (File file : files) {
                System.out.println("Processing: " + file.getName());
                if ( file.getName().endsWith("-aot.factories") ) {
                    Properties properties = new Properties();
                    try (InputStream inputStream = new FileInputStream(file)) {
                        properties.load(inputStream);
                    }
                    // 合并内容
                    for (String key : properties.stringPropertyNames()) {
                        String value = properties.getProperty(key);
                        mergedAotFactories.computeIfAbsent(key, k -> new ArrayList<>()).addAll(Arrays.asList(value.split(",")));
                    }
                } else {
                    String fileName = Splitter.on(".jar-").splitToList(file.getName()).get(1);
                    List<String> lines = Files.readAllLines(Paths.get(file.getPath()));
                    mergedTxtFactories.computeIfAbsent(fileName, k -> new ArrayList<>()).addAll(lines);
                }
            }
        }
//        files = springOutputDir.listFiles((dir, name) -> name.endsWith("-spring"));
//        if (files != null) {
//            for (File file : files) {
//                System.out.println("Processing: " + file.getName());
//                Properties properties = new Properties();
//                try (InputStream inputStream = new FileInputStream(file)) {
//                    properties.load(inputStream);
//                }
//
//                // 合并内容
//                for (String key : properties.stringPropertyNames()) {
//                    String value = properties.getProperty(key);
//                    mergedFactories.computeIfAbsent(key, k -> new ArrayList<>()).addAll(Arrays.asList(value.split(",")));
//                }
//            }
//        }
        String springDir = "/hxcloud/poc/micro-service-demo/AgentEnhancer/src/main/resources/META-INF";
        File  outputFile = new File(springDir, "spring.factories");
        // 写入合并后的结果到文件
        try (BufferedWriter writer = Files.newBufferedWriter(outputFile.toPath())) {
            for (Map.Entry<String, List<String>> entry : mergedFactories.entrySet()) {
                String key = entry.getKey();
                List<String> values = entry.getValue();
                // 去重（如果需要）
                Set<String> uniqueValues = new LinkedHashSet<>(values);
                writer.write(key + "=" + String.join(",", uniqueValues));
                writer.newLine();
            }
        }
        String springSDir = "/hxcloud/poc/micro-service-demo/AgentEnhancer/src/main/resources/META-INF/spring";
        outputFile = new File(springSDir, "aot.factories");
        // 写入合并后的结果到文件
        try (BufferedWriter writer = Files.newBufferedWriter(outputFile.toPath())) {
            for (Map.Entry<String, List<String>> entry : mergedAotFactories.entrySet()) {
                String key = entry.getKey();
                List<String> values = entry.getValue();
                // 去重（如果需要）
                Set<String> uniqueValues = new LinkedHashSet<>(values);
                writer.write(key + "=" + String.join(",", uniqueValues));
                writer.newLine();
            }
        }
        mergedTxtFactories.forEach((k,v)->{
            try {
                Files.write(Paths.get(springSDir, k), v);
            } catch (IOException e) {
            }
        });

        System.out.println("Merged spring.factories file created at: " + outputFile.getAbsolutePath());
    }
}
